package com.atguigu.tingshu.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private AlbumFeignClient albumFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * TradeVo 中包含 albumId 以及 购买项目类型
     * @param tradeVo
     * @return
     */
    @Override
    public OrderInfoVo trade(TradeVo tradeVo) {
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        // 创建需要后续封装对象中的属性
        // 订单原始金额
        BigDecimal originalAmount = new BigDecimal("0");
        // 减免总金额
        BigDecimal derateAmount = new BigDecimal("0");
        // 订单总价
        BigDecimal orderAmount = new BigDecimal("0");

        // 订单明细列表
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        // 订单减免明细列表
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        // VIP免费  完全付费
        // 判断购买类型 1001-专辑 1002-声音 1003-vip会员
        if (SystemConstant.ORDER_ITEM_TYPE_VIP.equals(tradeVo.getItemType())){
            // 会员处理 -- 先判断买哪种会员（付费类型）
            List<VipServiceConfig> vipServiceConfigs = userFeignClient.findAll().getData();
            for (VipServiceConfig vipServiceConfig : vipServiceConfigs) {
                // 判断类型（包年或者包月）
                if(vipServiceConfig.getId().equals(tradeVo.getItemId())){
                    // 获取价格
                    // 订单原价
                    originalAmount = vipServiceConfig.getPrice();
                    // 订单减免价格
                    derateAmount = vipServiceConfig.getPrice().subtract(vipServiceConfig.getDiscountPrice());
                    // 最终价格（即订单总价）
                    orderAmount = vipServiceConfig.getDiscountPrice();
                    // 订单明细对象
                    OrderDetailVo orderDetailVo = new OrderDetailVo();
                    orderDetailVo.setItemId(vipServiceConfig.getId());
                    orderDetailVo.setItemName(vipServiceConfig.getName());
                    orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
                    orderDetailVo.setItemPrice(orderAmount);
                    orderDetailVoList.add(orderDetailVo);
                    // 订单减免明细对象
                    OrderDerateVo orderDerateVo = new OrderDerateVo();
                    orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                    orderDerateVo.setDerateAmount(derateAmount);
                    orderDerateVo.setRemarks("会员折扣服务");
                    orderDerateVoList.add(orderDerateVo);
                }
            }

        }else if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(tradeVo.getItemType())){
            // 专辑处理 只允许购买整张专辑 ablumInfo中查询专辑折扣信息
            AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(tradeVo.getItemId()).getData();
            // 判断专辑是否打折
            if(albumInfo.getDiscount().compareTo(new BigDecimal("0")) > 0){
                // 专辑打折
                // 专辑购买---判断是否是会员 会员享受对应的专辑折扣 普通用户享受对应专辑折扣
                UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(albumInfo.getUserId()).getData();
                if(userInfoVo.getIsVip() == 1 && new Date().before(userInfoVo.getVipExpireTime())){
                    // 会员 -- 享受专属折扣
                    // 订单原价
                    originalAmount = albumInfo.getPrice();
                    // 订单总价 100 * 8 / 10 且保留两位小数
                    orderAmount = originalAmount.multiply(albumInfo.getVipDiscount()).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                    // 订单减免价格
                    derateAmount = originalAmount.subtract(orderAmount);
                    // 订单明细对象
                    OrderDetailVo orderDetailVo = new OrderDetailVo();
                    orderDetailVo.setItemId(albumInfo.getId());
                    orderDetailVo.setItemName(albumInfo.getAlbumIntro());
                    orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
                    // 项目价格
                    orderDetailVo.setItemPrice(originalAmount);
                    orderDetailVoList.add(orderDetailVo);
                    // 订单减免明细对象
                    OrderDerateVo orderDerateVo = new OrderDerateVo();
                    orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                    orderDerateVo.setDerateAmount(derateAmount);
                    orderDerateVo.setRemarks("会员专享折扣服务");
                    orderDerateVoList.add(orderDerateVo);
                }else {
                    // 非会员 -- 享受非会员专辑折扣
                    originalAmount = albumInfo.getPrice();
                    // 订单总价 100 * 8 / 10 且保留两位小数
                    orderAmount = originalAmount.multiply(albumInfo.getDiscount()).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                    // 订单减免价格
                    derateAmount = originalAmount.subtract(orderAmount);
                    // 订单明细对象
                    OrderDetailVo orderDetailVo = new OrderDetailVo();
                    orderDetailVo.setItemId(albumInfo.getId());
                    orderDetailVo.setItemName(albumInfo.getAlbumIntro());
                    orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
                    // 项目价格（原价）
                    orderDetailVo.setItemPrice(originalAmount);
                    orderDetailVoList.add(orderDetailVo);
                    // 订单减免明细对象
                    OrderDerateVo orderDerateVo = new OrderDerateVo();
                    orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                    orderDerateVo.setDerateAmount(derateAmount);
                    orderDerateVo.setRemarks("普通用户折扣服务");
                    orderDerateVoList.add(orderDerateVo);
                }
            }else {
                // 专辑不打折 vip免费只是有权试听专属vip的专辑
                // 原价
                originalAmount = albumInfo.getPrice();
                // 订单减免价格为0
                // 订单总价 == 原价
                orderAmount = originalAmount;
                // 订单明细对象
                OrderDetailVo orderDetailVo = new OrderDetailVo();
                orderDetailVo.getItemId();
                orderDetailVo.setItemName(albumInfo.getAlbumIntro());
                orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
                // 订单价格
                orderDetailVo.setItemPrice(orderAmount);
                orderDetailVoList.add(orderDetailVo);
                // 订单减免明细对象 -- 应该不做处理
            }

        }else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(tradeVo.getItemType())){
            // 声音处理 允许购买单个声音，但是不打折
        }
        // 交易订单号
        // 防止重复提交订单，且存入redis以便后续进行幂等性判断
        String tradeNo = IdUtil.fastSimpleUUID();
        orderInfoVo.setTradeNo(tradeNo);
        // 不可使用setNx 因为后续再提交订单之后需要进行删除，若使用setNx，则用户无容错，只能提交一次
        redisTemplate.opsForValue().set(RedisConstant.ORDER_TRADE_NO_PREFIX + tradeNo, tradeNo, RedisConstant.ORDER_TRADE_EXPIRE, TimeUnit.SECONDS);
        orderInfoVo.setItemType(tradeVo.getItemType());
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        // 时间戳
        orderInfoVo.setTimestamp(System.currentTimeMillis());
        // 签名,防止订单被篡改
        // BeanUtil.beanToMap 的第二个参数：是否忽略null值
        // 第三个参数：是否使用驼峰转下划线
        Map<String, Object> mapSign = BeanUtil.beanToMap(orderInfoVo, false, true);
        String sign = SignHelper.getSign(mapSign);
        orderInfoVo.setSign(sign);


        return orderInfoVo;
    }
}
